cmake_minimum_required(VERSION 3.16)
project(grpc_bidirectional_example)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# 设置目录结构
set(SRC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src)
set(INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include)
set(BUILD_DIR ${CMAKE_CURRENT_BINARY_DIR})

# 查找必要的包
find_package(Threads REQUIRED)
find_package(PkgConfig REQUIRED)
find_package(Protobuf REQUIRED)
find_package(gRPC REQUIRED)

# 生成protobuf和gRPC代码
set(PROTO_FILES ${SRC_DIR}/chat.proto)
set(PROTO_SRC_DIR ${BUILD_DIR}/generated)
file(MAKE_DIRECTORY ${PROTO_SRC_DIR})

# 自定义protobuf生成规则
get_filename_component(PROTO_NAME ${PROTO_FILES} NAME_WE)
set(PROTO_SRCS ${PROTO_SRC_DIR}/${PROTO_NAME}.pb.cc)
set(PROTO_HDRS ${PROTO_SRC_DIR}/${PROTO_NAME}.pb.h)
set(GRPC_SRCS ${PROTO_SRC_DIR}/${PROTO_NAME}.grpc.pb.cc)
set(GRPC_HDRS ${PROTO_SRC_DIR}/${PROTO_NAME}.grpc.pb.h)

add_custom_command(
    OUTPUT ${PROTO_SRCS} ${PROTO_HDRS}
    COMMAND ${Protobuf_PROTOC_EXECUTABLE}
    ARGS --cpp_out=${PROTO_SRC_DIR} -I${SRC_DIR} ${PROTO_FILES}
    DEPENDS ${PROTO_FILES}
    COMMENT "Generating protobuf files"
)

add_custom_command(
    OUTPUT ${GRPC_SRCS} ${GRPC_HDRS}
    COMMAND ${Protobuf_PROTOC_EXECUTABLE}
    ARGS --grpc_out=${PROTO_SRC_DIR} --plugin=protoc-gen-grpc=`which grpc_cpp_plugin` -I${SRC_DIR} ${PROTO_FILES}
    DEPENDS ${PROTO_FILES}
    COMMENT "Generating gRPC files"
)

# 包含目录
include_directories(${INCLUDE_DIR})
include_directories(${PROTO_SRC_DIR})

# 服务器可执行文件
add_executable(chat_server
    ${SRC_DIR}/server.cpp
    ${PROTO_SRCS}
    ${GRPC_SRCS}
)

target_link_libraries(chat_server
    gRPC::grpc++
    protobuf::libprotobuf
    Threads::Threads
)

# 客户端可执行文件
add_executable(chat_client
    ${SRC_DIR}/client.cpp
    ${PROTO_SRCS}
    ${GRPC_SRCS}
)

target_link_libraries(chat_client
    gRPC::grpc++
    protobuf::libprotobuf
    Threads::Threads
)

# 设置输出目录
set_target_properties(chat_server chat_client
    PROPERTIES
    RUNTIME_OUTPUT_DIRECTORY ${BUILD_DIR}
)